package com.edt.ichannel.api.service.impl;

import cc.edt.iceutils2.string.IceStringUtils;
import cc.edt.iceutils3.json.IceFastJsonUtils;
import com.edt.ichannel.api.common.constant.CommonConstant;
import com.edt.ichannel.api.common.entity.ActionResult;
import com.edt.ichannel.api.entiy.local.EntityForCallUnicomPayBatch;
import com.edt.ichannel.api.entiy.local.EntityFormUnicomPayParam;
import com.edt.ichannel.api.entiy.local.HttpPostParamsWoPay;
import com.edt.ichannel.api.service.*;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;

@Service
public class PayServiceImpl implements PayService {

    private Logger logger = LogManager.getLogger(PayServiceImpl.class);
    @Resource
    private ValidateService validateService;
    @Resource(name = "redisTemplate")
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private EdtApiService edtApiService;

    @Resource
    private WechatService wchatService;

    @Resource
    private StaffService staffService;

    @Resource
    private ExpansionService expansionService;

    @Override
    public ActionResult  pay(HttpPostParamsWoPay params) {
        ActionResult actionResult = validateService.validatePayParam(params);
        if (actionResult.isSuccess()) {
            String lockKey = CommonConstant.LOCK_KEY_EXPANSION+params.getExpansionId();
            if(redisTemplate.opsForValue().setIfAbsent(lockKey,params.getExpansionId())){
                redisTemplate.expire(lockKey,30,TimeUnit.SECONDS);
                actionResult = validateService.valistaPayAccount(params);
                if(actionResult.isSuccess()){
                    actionResult = edtApiService.woPay(params);
                    if (actionResult.isSuccess()){
                        if(updateExpansionAccount(params)){
                            logger.info("支付结果入库完毕"+IceFastJsonUtils.toJsonString(actionResult));
                        }else{
                            actionResult.setMessage("提现接口调用成功但是 更改账户出现异常需要手动处理 "+"余额："+params.getAmount()+"渠道："+params.getExpansionId());
                        }
                    }
                }
                redisTemplate.delete(lockKey);
            }else{
                actionResult.setSuccess(false);
                actionResult.setMessage("账户正在被使用："+params.getExpansionId());
                logger.info("账户正在被使用："+params.getExpansionId());
            }
        }
        if (!IceStringUtils.isBlank(params.getOpenid()))
        {
            logger.info("异步调用开始");
            wchatService.sendTemplateMessage(params.getAmount(),params.getFee(),params.getOpenid(),actionResult.isSuccess(),actionResult.getMessage());
        }
        logger.info("返回结果：" +IceFastJsonUtils.toJsonString(actionResult));
        return actionResult;
    }

    @Override
    public ActionResult payStaff(HttpPostParamsWoPay params) {
        ActionResult actionResult = validateService.validatePayParamStaff(params);
        if (actionResult.isSuccess()) {
            String lockKey = CommonConstant.LOCK_KEY_STAFF+params.getStaffId();
            if(redisTemplate.opsForValue().setIfAbsent(lockKey,params.getStaffId())){
                redisTemplate.expire(lockKey,30,TimeUnit.SECONDS);
                actionResult = validateService.valistaStaffAccount(params);
                if(actionResult.isSuccess()){
                    actionResult = edtApiService.woPay(params);
                    if (actionResult.isSuccess()){
                        if(updateStaffAccount(params)){
                            logger.info("支付结果入库完毕"+IceFastJsonUtils.toJsonString(actionResult));
                        }else{
                            actionResult.setMessage("提现接口调用成功但是 更改账户出现异常需要手动处理 "+"余额："+params.getAmount()+"人员："+params.getStaffId());
                        }
                    }
                }
                redisTemplate.delete(lockKey);
            }else{
                actionResult.setSuccess(false);
                actionResult.setMessage("账户正在被使用");
                logger.info("账户正在被使用");
            }
        }
        if (!IceStringUtils.isBlank(params.getOpenid()))
        {
            logger.info("异步调用开始");
            wchatService.sendTemplateMessage(params.getAmount(),params.getFee(),params.getOpenid(),actionResult.isSuccess(),actionResult.getMessage());
        }
        logger.info("返回结果：" +IceFastJsonUtils.toJsonString(actionResult));
        return actionResult;
    }

    @Override
    public ActionResult unicomPay(EntityFormUnicomPayParam params) {
        ActionResult result = edtApiService.unicomPay(params);
        if (!IceStringUtils.isBlank(params.getOpenId()))
        {
            logger.info("异步调用开始");
            wchatService.sendTemplateMessage(params.getMoney(),"0",params.getOpenId(),result.isSuccess(),result.getMessage());
        }
        return result;
    }

    @Override
    public ActionResult unicomPayBatch(EntityForCallUnicomPayBatch params) {
        return edtApiService.unicomPayBatch(params.getParamList(),params.getTotalMoney());
    }


    /**
     * 提现成功次数记录到redis 中（过期时间 ：截止到当天晚上24点）
     *
     * @param key key
     * @author 李爽
     * @date 2018/2/8 15:46
     */
    private void setWoPayCount(String key) {

        int dayCounts = redisTemplate.opsForValue().get(key) == null ? 0 : Integer.parseInt(redisTemplate.opsForValue().get(key).toString());
        if (dayCounts == 0) {
            long secondsLeftToday = 86400 - DateUtils.getFragmentInSeconds(Calendar.getInstance(), Calendar.DATE);
            redisTemplate.opsForValue().set(key, 1, secondsLeftToday, TimeUnit.SECONDS);
        } else {
            redisTemplate.opsForValue().increment(key, 1);
        }
        logger.info("增加成功次数redis完毕");
    }


    private  boolean updateStaffAccount(HttpPostParamsWoPay params){
        try{
            BigDecimal amount = new BigDecimal(params.getAmount());
            staffService.minusStaffAccouintMoney(amount.divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP).doubleValue(),params.getStaffId());
            logger.debug("拓展人提现：沃支付--支付成功次数加1");
            setWoPayCount(CommonConstant.CONFIG_WO_STAFF_REDIS_PAY_KEY+params.getStaffId());
            return true;

        }catch (Exception e){
            e.printStackTrace();
            logger.info("提现接口调用成功 但是 更改账户出现异常："+e.getMessage());
            return false;

        }
    }

    private  boolean updateExpansionAccount(HttpPostParamsWoPay params){
        try {
            BigDecimal amount = new BigDecimal(params.getAmount());
            expansionService.minusExpansionCountMoney(amount.divide(new BigDecimal(100),2,BigDecimal.ROUND_HALF_UP).doubleValue(),params.getExpansionId());
            logger.debug("沃支付--支付成功次数加1");
            setWoPayCount(CommonConstant.CONFIG_WO_REDISPAYKEY+params.getExpansionId());
            return true;
        }catch (Exception e){
            e.printStackTrace();
            logger.info("提现接口调用成功 但是 更改账户出现异常："+e.getMessage());
            return false;

        }
    }
}
